package com.i.piccommon.util;

import cn.hutool.core.io.IoUtil;
import com.i.piccommon.config.MinioConfig;
import io.minio.*;
import io.minio.http.Method;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

/**
 * @author lewis
 * @type class
 * @description
 * @since 2024/10/24
 */
@Slf4j
public class MinioUtil {
    private final MinioClient minioClient;
    private final MinioConfig minioConfig;

    public MinioUtil(MinioClient minioClient, MinioConfig minioConfig) {
        this.minioClient = minioClient;
        this.minioConfig = minioConfig;
    }

    /**
     *  判断bucket 是否存在不存在创建
     */
    public boolean existBucket(String bucketName) {
        boolean exists;
        try {
            exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if(!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                exists = true;
            }
        } catch (Exception e) {
            exists = false;
        }
        return exists;
    }
    /**
     * 删除bucket
     */
    public Boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 上传文件
     * @param file
     * @param filename
     */
    public void upload(MultipartFile file, String filename) {
        try {
            InputStream stream = file.getInputStream();
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(filename)
                    .stream(stream,file.getSize(),-1)
                    .contentType(file.getContentType())
                    .build());
        } catch (Exception e) {
            log.error("上传文件失败");
        }
    }

    /**
     * 获取文件访问地址(有过期时间)
     * @param fileName
     * @param time
     * @param timeUnit
     * @return
     */
    public String getExpireFileUrl(String fileName, int time, TimeUnit timeUnit) {
        try {
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .expiry(time,timeUnit)
                    .build());
        } catch (Exception e) {
            log.error("获取文件访问地址失败(有过期时间)");
        }
        return null;
    }

    /**
     *  获取文件访问地址
     * @param fileName
     * @return
     */
    public String getFileUrl(String fileName) {
        try {
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .build());
        } catch (Exception e) {
            log.error("获取文件地址事变");
        }
        return null;
    }

    /**
     * 下载文件
     * @param response
     * @param fileName
     */
    public void download(HttpServletResponse response, String fileName) {
        InputStream in = null;
        try {
            StatObjectResponse statObjectResponse = minioClient.statObject(StatObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .build());
            response.setContentType(statObjectResponse.contentType());
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
            in = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .build());
            IoUtil.copy(in,response.getOutputStream());
        } catch (Exception e) {
            log.error("下载文件失败");
        }finally {
            if(in != null) {
                try {
                    in.close();
                }catch (IOException e){
                    log.error("关闭资源失败");
                }
            }
        }
    }

    /**
     * 删除文件
     * @param fileName
     */
    public void delete(String fileName) {
        try {
            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .build());
        } catch (Exception e) {
            log.error("删除文件失败");
        }
    }
}

